from flask import session, render_template, current_app, jsonify, request, g

from info import constants, db
from info.models import User, News, Category
from info.utils.commons import user_login_data
from info.utils.response_code import RET
from . import news_blue


@news_blue.route('/')
def hello_world():
    # 右上角个人用户信息展示
    # 1. 获取session信息
    # 2. 返回给模板，由模板判断并渲染
    user_id = session.get('user_id')
    try:
        user = User.query.filter(user_id == User.id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='用户信息查询失败')
    # 新闻排行
    # 1. 从mysql数据库中，根据点击量进行排序，返回给模板
    # 2. 返回结果，由模板渲染
    # 3. 使用过滤器，对前三个新闻的小图标进行装饰
    try:
        news_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='新闻排行数据获取失败')
    news_click_list = []
    for news in news_list:
        news_click_list.append(news.to_dict())

    # 新闻分类
    # 1. 从mysql查询分类
    # 2. 返回查询结果
    try:
        news_Category = Category.query.filter().all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='新闻分类查询失败')
    news_Category_list = []
    for category in news_Category:
        news_Category_list.append(category.to_dict())

    data = {
        'user_info': user.to_dict() if user else None,
        'news_click_list': news_click_list,
        'category_list': news_Category_list
    }

    return render_template('news/index.html', data=data)


@news_blue.route('/favicon.ico')
def favicon():
    return current_app.send_static_file('news/favicon.ico')


@news_blue.route('/news_list')
def news_list():
    """
    新闻列表展示
    1. 获取参数cid、page、per_page
    2. 类型转换
    3. 查询对应分类下的新闻数据
    4. 返回数据
    :return:
    """
    cid = request.args.get('cid')
    page = request.args.get('page', 1)
    per_page = request.args.get('per_page', 10)
    try:
        cid, page, per_page = int(cid), int(page), int(per_page)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg='参数格式不正确')
    filter = []
    if cid > 1:
        filter.append(News.category_id == cid)
    try:
        news = News.query.filter(*filter).order_by(News.create_time.desc()).paginate(page, per_page, False)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='新闻列表查询失败')
    if not news:
        Category.news_list.append(news)
    # 获取查询数据
    items = news.items
    # 获取总页数
    totalPage = news.pages
    # 获取当前页
    currentPage = news.page

    news_list = []
    for news in items:
        news_list.append(news.to_dict())

    return jsonify(errno=RET.OK, errmsg='OK', cid=cid, currentPage=currentPage, newsList=news_list, totalPage=totalPage)


@news_blue.route('/<int:news_id>')
def news_detail(news_id):
    """
    新闻详情展示
    1. 获取新闻id
    2. 在mysql中查询对应的新闻
    3. 返回数据，由模板渲染
    :return:
    """
    try:
        news_id = int(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据格式转换错误')

    try:
        news_detail = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='对应的详细新闻查询失败')
    # 查询详情后，使该新闻的点击量+1
    news_detail.clicks += 1
    try:
        db.session.add(news_detail)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据修改失败')
    news_detail.to_dict()
    # 右上角个人用户信息展示
    # 1. 获取session信息
    # 2. 返回给模板，由模板判断并渲染
    user_id = session.get('user_id')
    try:
        user = User.query.filter(user_id == User.id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='用户信息查询失败')
    # 新闻排行
    # 1. 从mysql数据库中，根据点击量进行排序，返回给模板
    # 2. 返回结果，由模板渲染
    # 3. 使用过滤器，对前三个新闻的小图标进行装饰
    try:
        news_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='新闻排行数据获取失败')
    news_click_list = []
    for news in news_list:
        news_click_list.append(news.to_dict())

    # 新闻分类
    # 1. 从mysql查询分类
    # 2. 返回查询结果
    try:
        news_Category = Category.query.filter().all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='新闻分类查询失败')
    news_Category_list = []
    for category in news_Category:
        news_Category_list.append(category.to_dict())

    data = {
        'user_info': user.to_dict() if user else None,
        'news_click_list': news_click_list,
        'category_list': news_Category_list,
        'news_id': news_id
    }
    # print(data['user_info'])
    return render_template('news/detail.html', news=news_detail, data=data)


@news_blue.route('/news_collect', methods=['POST'])
@user_login_data
def news_collect():
    """
    新闻收藏
    1. 获取参数new_id、action
    2. 检验参数完整性，其中action的值：指定两个值：'collect', 'cancel_collect'
        验证用户是否登陆
    3. 判断新闻是否已经收藏
    4. 判断action的值是'collect', 还是'cancel_collect'
    5. 返回结果
    :return:
    """
    user = g.user
    news_id = request.json.get('news_id')
    action = request.json.get('action')
    if not all([news_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')
    if action not in ['collect', 'cancel_collect']:
        return jsonify(errno=RET.DATAERR, errmsg='参数不在范围内')
    if not user:
        return jsonify(errno=RET.NODATA, errmsg='用户未登录')
    if news_id in user.collection_news:
        return jsonify(errno=RET.DATAEXIST, errmsg='该新闻已收藏')

    # 验证新闻是否存在
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='新闻数据查询失败')

    if not news:
        return jsonify(errno=RET.NODATA, errmsg='无新闻数据')

    is_collect = None
    if action == 'collect':
        user.collection_news.append(news)
        is_collect = True
    else:
        user.collection_news.remove(news)
        is_collect = False

    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据提交到mysql数据库失败')
    return jsonify(errno=RET.OK, errmsg='OK', is_collect=is_collect)

